1 Introduction

This document contains the results and analysis of my second experiment for my first Qualifying Paper towards the PhD in Linguistics at Stanford University1.

2 Methods

2.1 The Experiment

The experiment analyzed herein was an online maze task study, wherein participants read a sentence such as “David is a congressperson from Virginia. He likes cycling.” For each of the 20 critical items, participants were randomly assigned to one of four conditions, the critical regions of which are enumerated and exemplified here:

  1. Male-congruent: David is a congressman
  2. Male-neutral: David is a congressperson
  3. Female-congruent: Sally is a congresswoman
  4. Female-neutral: Sally is a congressperson

Participants proceeded through the sentences by pressing a keyboard key which corresponded to the grammatical continuation of the sentence, and reading pair of grammatical and distractor items at a time. They were then asked attention check questions at the end of each sentence; attention check questions never explicitly invoked gender. Rather, they asked about the character’s home states. For a hands-on look at the experiment, you can click here to go to the same webpage particpants were directed to for the task.

##Participants We originally ran the experiment on 200 participants, recruited through the online participant recruitment platform Prolific. The mean time of the experiment was 5.39 minutes, and participants were paid $1.75 for their participation2. The only restrictions placed on participants were that they:

  1. Were born in the United States
  2. Lived in the United States at the time of participation
  3. Spoke English as a first language
  4. Had not participated in the norming study for the stimuli

These requirements were implemented in order to assure that speakers came from at least somewhat similar linguistic backgrounds, as certain lexical items in the study (such as congressperson) are quite localized to the United States.

After this initial run of the experiment, we found that there was a dearth of conservative or Republican-aligned participants. As a result, we ran the experiment again, this time on 98 self-identified Republicans. This was achieved by adding a filter on Prolific so that only Republican-identified individuals could see the task. The rest of the experiment, including payment, was exactly the same, except that an additional disclaimer that participants could not use the FireFox browser experiment, after the first run revealed an incompatibility between JavaScript and FireFox. The two runs of the experiment amounted in a total of 298 participants who completed the task.

3 Prepping the Data

Before we can do much of anything with the data, we need to make sure it’s usable! This means filtering out all unimportant or extraneous trials, running exclusion criteria, and adding additional trial and item-level data that will be necessary later in the analysis.

3.1 Packages

For this analysis, we require the following packages:

library(ggplot2) 
library(tidyverse) 
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ──────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✓ tibble  3.1.2     ✓ dplyr   1.0.6
✓ tidyr   1.1.3     ✓ stringr 1.4.0
✓ readr   1.4.0     ✓ forcats 0.5.1
✓ purrr   0.3.4     
── Conflicts ─────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()
library(lme4) 
Loading required package: Matrix

Attaching package: ‘Matrix’

The following objects are masked from ‘package:tidyr’:

    expand, pack, unpack
library(stringr)
library(languageR)
library(lmerTest)

Attaching package: ‘lmerTest’

The following object is masked from ‘package:lme4’:

    lmer

The following object is masked from ‘package:stats’:

    step
library(reshape2)

Attaching package: ‘reshape2’

The following object is masked from ‘package:tidyr’:

    smiths
source("helpers.R")

3.2 Reading in the Data

In the first instance, we need to read in the data, which has been pre-merged from both runs of the experiment. We will also in this chunk filter out all of the example trials, as well as all the data points that are from non-critical trials.

all_data <- read.csv('merged_all.csv') %>%
  filter(trial_id!= 'example') %>%
  filter(region=='critical')

3.3 Running Exclusion Criteria

Now, we want to exclude any participants who failed to answer at least 85% of the attention check questions correctly. We do this by creating a list of all participants who scored less than 85% on these checks, and then cross-referencing this list with all data points, removing any data points whose participants were in the exclusion list.

exclusion <- all_data %>% group_by(workerid) %>%
  summarise(accuracy = mean(response_correct)) %>%
  mutate(exclude = ifelse(accuracy < 0.85,'Yes','No')) %>% 
  filter(exclude == 'Yes')

all_data <- all_data[!(all_data$workerid %in% exclusion$workerid),] %>%
  filter(rt !='null')

We also want to filter out all trials in which the reading time for the critical item was more than 2.5 standard deviations from the mean reading time on that lexical item across all participants.

all_data <- all_data %>% group_by(trial_id) %>% mutate(id_mean = mean(log(rt))) %>% mutate(exclusion = (log(rt) < mean(log(rt)) - 2sd(log(rt))|(log(rt) > mean(log(rt)) + 2sd(log(rt))))) %>% ungroup() %>% filter(exclusion==FALSE)

This results in 238 trials being removed from the 5580 we got after the by-participant exclusions. We now have 5342 trials we can use for analysis.

3.4 Adding in Additional Important Trial Information

Now that we have only the rows we want, let’s add some new columns, which will contain important information for each data point. Here, we will be adding:

  • Gender Ideology Subscores
  • Trial Genders
  • Trial Morphology Types
  • Critical Item Length & Length-Controlled Residuals
  • Trial Congruency
  • Partipant Political Affiliation

Ideally, I would’ve added all of these but the first when I actually created the stimuli and logged responses, but I forgot to! Luckily, R allows us to do this post-hoc fairly straightforwardly… which is good, since these features will be critical in our data visualization and analysis.

3.4.1 Defining Gender Subscores


The question under investigation here is whether or not individuals’ conceptions of gender affect how they process gendered and gender-neutral forms of English personal and professional titles.

In order to examine this, we need to quanify participants’ ideological views! Here we have adopted the 13-item Social Roles Questionnaire put forth in Baber & Tucker (2006). Questions 1-5 correlate to the ‘Gender Transcendent’ subscale, and questions 6-13 correspond to the ‘Gender Linked’ subscale. Each item is scored on a scale of 0-100. So, the first thing we want to do is make two lists of columns which correspond to these two subscales, since the questions are stored individually in the data:

gender_transcendence_cols <- c('subject_information.gender_q1','subject_information.gender_q2','subject_information.gender_q3','subject_information.gender_q4','subject_information.gender_q5')

gender_linked_cols <- c('subject_information.gender_q6','subject_information.gender_q7','subject_information.gender_q8','subject_information.gender_q9','subject_information.gender_q10','subject_information.gender_q11','subject_information.gender_q12','subject_information.gender_q13')


Now we can use the mutate() method on all_data to add two new columns, one for each subscale. We tell R to take the means of the specified columns in [column_names] of all_data for each individual row: rowMeans(all_data[column_names]). We also have to subtract this mean from 100 in the case of the ‘Gender Transcendent’ subscale, since it is inversely scored. Finally, we can create an average total score regardless of subscores, simply by meaning the two subscores we already have.

all_data <- all_data %>%
  mutate(gender_trans = 100 - (rowMeans(all_data[gender_transcendence_cols]))) %>%
  mutate(gender_link = rowMeans(all_data[gender_linked_cols])) 

gender_all = c('gender_trans','gender_link')

all_data <- all_data %>%
  mutate(gender_total = rowMeans(all_data[gender_all]))

3.4.2 Adding Gender


We also want to add whether the trial included a female or male referent (but also, like, destroy the binary!). In order to do this, we’ll just add a trial_gender column that says ‘female’ if the condition was either ‘neutral_female’ or ‘congruent_female’. Otherwise, we want the trial_gender to say ‘male’.

all_data <- all_data %>%
  mutate(trial_gender = ifelse(condition=='neutral_female' | condition == 'congruent_female','female','male'))

all_data %>%
  select(workerid,rt,condition,trial_id,trial_gender)

3.4.3 Adding Morphology Type


Now we want to add whether or not the lexeme’s neutral form is developed by compounding (as in ‘congress-person’) or by the adoption of the male form (as in ‘actor’ being used more for both men and women). In this study, we only have six lexemes of the latter type, so we’ll just tell R to assign those a morph_type value of ‘adoption’ (for ‘male adoption’), and all else will be assigned a value of ‘compound’.

all_data <- all_data%>%
  mutate(morph_type = ifelse(lexeme!= 'actor' & lexeme!= 'host' & lexeme !='hunter' & lexeme!= 'villain' & lexeme!= 'heir' & lexeme!= 'hero','compound','adoption'))

all_data %>%
  select(rt,lexeme,morph_type)

3.4.4 Adding Form Length & Length-Controlled Residuals


Another important factor we want to explore is the length of the critical item! In order to add this, we simply create a new column form_length and tell R to input as that column’s value the length of the string that appears in that row’s form column, which corresponds to the orthograpic form of the critical item in that trial. Note that this will include spaces in the count!

all_data <- all_data %>%
  mutate(form_length = str_length(form))

simple_model <- lm(log(rt)~form_length, data = all_data)

all_data <- all_data %>%
  mutate(resid_rt = resid(simple_model))
summary(simple_model)

Call:
lm(formula = log(rt) ~ form_length, data = all_data)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.8837 -0.3067 -0.0704  0.2480  3.1990 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 6.969210   0.023635 294.863  < 2e-16 ***
form_length 0.011369   0.002428   4.683 2.95e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.4301 on 2980 degrees of freedom
Multiple R-squared:  0.007305,  Adjusted R-squared:  0.006972 
F-statistic: 21.93 on 1 and 2980 DF,  p-value: 2.954e-06

Now that we have these, we can run a simple linear regression which will show us the effect of orthographic length on reading time. Then we add a new column in the data which is the residual reading time, or the reading time in log space AFTER we control for the effects of orthographic length.

3.4.5 Adding Congruency Column


We also want to make sure we have a column which records whether or not the trial was gender-congruent (as in ‘Shelby is a congresswoman’) or gender neutral (as in ‘Shelby is a congressperson’). We add a trial_congruency column, which is valued as ‘congruent’ if that row’s condition is one of the two congruent conditions. Otherwise, it gets valued as ‘neutral’.

all_data <- all_data %>%
  mutate(trial_congruency = ifelse(condition=='congruent_male' | condition == 'congruent_female','congruent','neutral'))

3.4.6 Adding Large Political Macrocategories


Finally, we can classify participants by their particular political alignment; we can construe this broadly as “Republicans” vs. “Democrats”, with those who declined to state a preference, or placed themselves in the middle, as “Non-Partisan”.

all_data <- all_data %>%
  mutate(poli_party = ifelse(subject_information.party_alignment == 1 | subject_information.party_alignment == 2,'Republican',ifelse(subject_information.party_alignment == 4 | subject_information.party_alignment == 5,'Democrat','Non-Partisan')))

4 Data Visualization

Now we can start analysing the data by means of data visualization.

inauguration_2021 = c("#5445b1", "#749dae", "#f3c483", "#5c1a33", "#cd3341","#f7dc6a")

4.1 Ideology by Age

ggplot(all_data, aes(x=subject_information.age, y=gender_total)) + 
  geom_point(alpha=.5) + 
  geom_smooth(method = 'lm', size=1.2)

4.2 Reading Time by Gender Ideology

ggplot(all_data, aes(x=gender_total, y=resid_rt, color=trial_congruency)) + 
  geom_point(alpha=.5) + 
  geom_smooth(method = 'lm', size=1.2) + 
  theme_minimal()

4.3 Reading Time by Age

4.4 Reading Time by Congruency and Gender

agg_speaker_mean_con <- all_data %>%
  group_by(condition,workerid) %>%
  summarize(MeanRT=mean(resid_rt))
`summarise()` has grouped output by 'condition'. You can override using the `.groups` argument.
all_data %>%
  group_by(condition,trial_gender) %>%
  summarize(MeanRT = mean(resid_rt), CI.Low = ci.low(resid_rt), CI.High = ci.high(resid_rt)) %>%
  mutate(YMin = MeanRT - CI.Low, YMax = MeanRT + CI.High) %>%
  ggplot(aes(x=condition,y=MeanRT,color=trial_gender)) + 
  geom_point(size=3) + 
  geom_jitter(data = agg_speaker_mean_con, aes(y=MeanRT),alpha=.1,color='darkred') + 
  geom_errorbar(aes(ymin=YMin,ymax=YMax), width=.25) + 
  scale_color_manual(values = inauguration_2021) + 
  theme_minimal()
`summarise()` has grouped output by 'condition'. You can override using the `.groups` argument.

4.5 Reading Time by Congruency, Gender, and Lexical Item

all_data %>%
  group_by(condition,trial_gender,trial_congruency,lexeme) %>%
  summarize(MeanRT = mean(resid_rt), CI.Low = ci.low(resid_rt), CI.High = ci.high(resid_rt)) %>%
  mutate(YMin = MeanRT - CI.Low, YMax = MeanRT + CI.High) %>%
  ggplot(aes(x=condition,y=MeanRT,color=trial_gender,shape=trial_congruency)) + 
  geom_point(size=3) +
  geom_errorbar(aes(ymin=YMin,ymax=YMax), width=.25) + 
  facet_wrap(~ lexeme) +
  theme(axis.text.x = element_text(angle = 45, vjust = .7, hjust=.7)) + 
  scale_color_manual(values = inauguration_2021) + 
  facet_wrap(~lexeme)
`summarise()` has grouped output by 'condition', 'trial_gender', 'trial_congruency'. You can override using the `.groups` argument.

4.5.1 Male Adoptions Only

all_data %>%
  filter(morph_type == "adoption") %>%
  group_by(condition,trial_gender,trial_congruency,lexeme) %>%
  summarize(MeanRT = mean(resid_rt), CI.Low = ci.low(resid_rt), CI.High = ci.high(resid_rt)) %>%
  mutate(YMin = MeanRT - CI.Low, YMax = MeanRT + CI.High) %>%
  ggplot(aes(x=condition,y=MeanRT,color=trial_gender,shape=trial_congruency)) + 
  geom_point(size=3) +
  geom_errorbar(aes(ymin=YMin,ymax=YMax), width=.25) + 
  facet_wrap(~ lexeme) +
  theme(axis.text.x = element_text(angle = 45, vjust = .7, hjust=.7)) + 
  scale_color_manual(values = inauguration_2021) + 
  facet_wrap(~lexeme)
`summarise()` has grouped output by 'condition', 'trial_gender', 'trial_congruency'. You can override using the `.groups` argument.

4.5.2 Compounds only

all_data %>%
  filter(morph_type == "compound") %>%
  group_by(condition,trial_gender,trial_congruency,lexeme) %>%
  summarize(MeanRT = mean(resid_rt), CI.Low = ci.low(resid_rt), CI.High = ci.high(resid_rt)) %>%
  mutate(YMin = MeanRT - CI.Low, YMax = MeanRT + CI.High) %>%
  ggplot(aes(x=condition,y=MeanRT,color=trial_gender,shape=trial_congruency)) + 
  geom_point(size=3) +
  geom_errorbar(aes(ymin=YMin,ymax=YMax), width=.25) + 
  facet_wrap(~ lexeme) +
  theme(axis.text.x = element_text(angle = 45, vjust = .7, hjust=.7)) + 
  scale_color_manual(values = inauguration_2021) + 
  facet_wrap(~lexeme)
`summarise()` has grouped output by 'condition', 'trial_gender', 'trial_congruency'. You can override using the `.groups` argument.

4.6 Raw Reading Time by Trial Gender

temp <- all_data %>%
  group_by(trial_gender) %>%
  summarize(MeanRT = mean(rt), CI.Low = ci.low(rt), CI.High = ci.high(rt)) %>%
  mutate(YMin = MeanRT - CI.Low, YMax = MeanRT + CI.High)

dodge = position_dodge(.9)
ggplot(data=temp, aes(x=trial_gender,y=MeanRT,fill=trial_gender)) + 
  geom_bar(stat='identity',position=dodge) + 
  geom_errorbar(aes(ymin=YMin,ymax=YMax),width=.25,position=dodge) +
  theme(legend.position = 'none')

dodge = position_dodge(.9)

all_data %>% 
  group_by(trial_gender) %>%
  summarize(MeanRT = mean(resid_rt)) %>%
  ggplot(aes(x=trial_gender,y=MeanRT,fill=trial_gender)) + 
  geom_bar(stat='identity',position=dodge) + 
  theme(legend.position = 'none')

4.7 Reading Time Residuals by Congruency

dodge = position_dodge(.9)

all_data %>% 
  group_by(trial_congruency) %>%
  summarize(MeanRT = mean(resid_rt)) %>%
  ggplot(aes(x=trial_congruency,y=MeanRT,fill=trial_congruency)) + 
  geom_bar(stat='identity',position=dodge) + 
  theme(legend.position = 'none')

4.8 My Morphological Type and Gender

all_data %>%
  group_by(condition,trial_gender,morph_type) %>%
  summarize(MeanRT = mean(resid_rt), CI.Low = ci.low(resid_rt), CI.High = ci.high(resid_rt)) %>%
  mutate(YMin = MeanRT - CI.Low, YMax = MeanRT + CI.High) %>%
  ggplot(aes(x=condition,y=MeanRT,color=trial_gender)) + 
  geom_point(size=3) + 
  geom_errorbar(aes(ymin=YMin,ymax=YMax), width=.25) + 
  scale_color_manual(values = inauguration_2021) + 
  facet_wrap(~morph_type) + 
  theme(axis.text.x = element_text(angle=45, vjust = 0.5))
`summarise()` has grouped output by 'condition', 'trial_gender'. You can override using the `.groups` argument.

4.9 Task Familiarity

agg_speaker_trial <- all_data %>%
  group_by(condition,workerid) %>%
  summarize(MeanRT=mean(resid_rt))
`summarise()` has grouped output by 'condition'. You can override using the `.groups` argument.

5 Model Analyses

6 Testing Models

test_model <- lm(resid_rt~trial_congruency*morph_type, data=all_data)
summary(test_model)

Call:
lm(formula = resid_rt ~ trial_congruency * morph_type, data = all_data)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.9005 -0.3021 -0.0725  0.2436  3.1904 

Coefficients:
                                           Estimate Std. Error t value Pr(>|t|)    
(Intercept)                                 0.04198    0.02044   2.054 0.040111 *  
trial_congruencyneutral                    -0.03333    0.02864  -1.164 0.244666    
morph_typecompound                         -0.10134    0.02434  -4.164 3.22e-05 ***
trial_congruencyneutral:morph_typecompound  0.13118    0.03422   3.834 0.000129 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.4279 on 2978 degrees of freedom
Multiple R-squared:  0.01097,   Adjusted R-squared:  0.009969 
F-statistic: 11.01 on 3 and 2978 DF,  p-value: 3.478e-07
test_model2 <- lm(resid_rt~trial_gender, data=all_data)
summary(test_model2)

Call:
lm(formula = resid_rt ~ trial_gender, data = all_data)

Residuals:
    Min      1Q  Median      3Q     Max 
-0.8799 -0.3054 -0.0716  0.2498  3.1953 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)
(Intercept)      -0.003744   0.011138  -0.336    0.737
trial_gendermale  0.007488   0.015751   0.475    0.635

Residual standard error: 0.4301 on 2980 degrees of freedom
Multiple R-squared:  7.583e-05, Adjusted R-squared:  -0.0002597 
F-statistic: 0.226 on 1 and 2980 DF,  p-value: 0.6345
compounds_only <- all_data %>%
  filter(morph_type == 'compound')
compounds_only <- compounds_only %>%
  mutate(ctrial_congruency = as.numeric(as.factor(trial_congruency))-mean(as.numeric(as.factor(trial_congruency)))) %>%
  mutate(ctrial_gender = as.numeric(as.factor(trial_gender))-mean(as.numeric(as.factor(trial_gender)))) %>%
  mutate(cgender_link = scale(gender_link)) %>%
  mutate(cgender_total = scale(gender_total))
compound_model <- lmer(resid_rt~ctrial_congruency*ctrial_gender*cgender_total + (1|workerid) + (1|lexeme) + (1|name),data = compounds_only)
boundary (singular) fit: see ?isSingular
summary(compound_model)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: resid_rt ~ ctrial_congruency * ctrial_gender * cgender_total +  
    (1 | workerid) + (1 | lexeme) + (1 | name)
   Data: compounds_only

REML criterion at convergence: 1516.9

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.9463 -0.6196 -0.1141  0.5120  5.1743 

Random effects:
 Groups   Name        Variance Std.Dev.
 workerid (Intercept) 0.072802 0.26982 
 name     (Intercept) 0.000000 0.00000 
 lexeme   (Intercept) 0.009709 0.09853 
 Residual             0.097840 0.31279 
Number of obs: 2089, groups:  workerid, 152; name, 24; lexeme, 14

Fixed effects:
                                                Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)                                     -0.01169    0.03492   33.77863  -0.335   0.7398    
ctrial_congruency                                0.10120    0.01386 1927.09399   7.301 4.16e-13 ***
ctrial_gender                                    0.02769    0.01387 1927.54232   1.996   0.0461 *  
cgender_total                                    0.05201    0.02294  150.06294   2.267   0.0248 *  
ctrial_congruency:ctrial_gender                 -0.01774    0.02780 1929.12259  -0.638   0.5234    
ctrial_congruency:cgender_total                  0.01692    0.01386 1926.12747   1.221   0.2224    
ctrial_gender:cgender_total                     -0.02024    0.01389 1927.94098  -1.457   0.1452    
ctrial_congruency:ctrial_gender:cgender_total   -0.04153    0.02776 1927.38754  -1.496   0.1349    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
                 (Intr) ctrl_c ctrl_g cgndr_ ctrl_cngrncy:ct_ ctrl_cngrncy:cg_ ctrl_g:_
ctrl_cngrnc       0.000                                                                
ctrial_gndr       0.000 -0.008                                                         
cgender_ttl       0.000  0.003 -0.001                                                  
ctrl_cngrncy:ct_ -0.002  0.001  0.003  0.001                                           
ctrl_cngrncy:cg_  0.002 -0.006  0.003  0.009 -0.002                                    
ctrl_gndr:_      -0.001  0.005  0.004  0.000  0.016           -0.003                   
ctrl_cn:_:_       0.001  0.001  0.016 -0.001  0.000            0.000            0.034  
optimizer (nloptwrap) convergence code: 0 (OK)
boundary (singular) fit: see ?isSingular
adoptions_only <- all_data %>%
  filter(morph_type == 'adoption')
adoptions_only <- adoptions_only %>%
  mutate(ctrial_congruency = as.numeric(as.factor(trial_congruency))-mean(as.numeric(as.factor(trial_congruency)))) %>%
  mutate(ctrial_gender = as.numeric(as.factor(trial_gender))-mean(as.numeric(as.factor(trial_gender)))) %>%
  mutate(cgender_link = scale(gender_link)) %>%
  mutate(cgender_total = scale(gender_total))
adoptions_model <- lmer(resid_rt~ctrial_congruency*ctrial_gender*cgender_total + (1|workerid) + (1|lexeme) + (1|name),data = adoptions_only)
boundary (singular) fit: see ?isSingular
summary(adoptions_model)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: resid_rt ~ ctrial_congruency * ctrial_gender * cgender_total +  
    (1 | workerid) + (1 | lexeme) + (1 | name)
   Data: adoptions_only

REML criterion at convergence: 780.7

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.2764 -0.6128 -0.1019  0.4977  7.0825 

Random effects:
 Groups   Name        Variance Std.Dev.
 workerid (Intercept) 0.05999  0.2449  
 name     (Intercept) 0.00000  0.0000  
 lexeme   (Intercept) 0.02594  0.1611  
 Residual             0.10261  0.3203  
Number of obs: 893, groups:  workerid, 152; name, 24; lexeme, 6

Fixed effects:
                                                Estimate Std. Error         df t value Pr(>|t|)   
(Intercept)                                     0.026404   0.069521   5.924863   0.380  0.71734   
ctrial_congruency                              -0.026661   0.022600 773.237762  -1.180  0.23848   
ctrial_gender                                  -0.024247   0.022594 773.262319  -1.073  0.28353   
cgender_total                                   0.061983   0.022598 148.801276   2.743  0.00684 **
ctrial_congruency:ctrial_gender                -0.033364   0.045588 779.086714  -0.732  0.46447   
ctrial_congruency:cgender_total                -0.009892   0.022408 764.311685  -0.441  0.65901   
ctrial_gender:cgender_total                    -0.011764   0.022586 769.611878  -0.521  0.60261   
ctrial_congruency:ctrial_gender:cgender_total   0.039454   0.045136 767.084621   0.874  0.38232   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
                 (Intr) ctrl_c ctrl_g cgndr_ ctrl_cngrncy:ct_ ctrl_cngrncy:cg_ ctrl_g:_
ctrl_cngrnc       0.000                                                                
ctrial_gndr       0.000  0.029                                                         
cgender_ttl      -0.001 -0.008  0.002                                                  
ctrl_cngrncy:ct_  0.003  0.001  0.005 -0.008                                           
ctrl_cngrncy:cg_ -0.003 -0.021 -0.013 -0.031  0.020                                    
ctrl_gndr:_       0.001 -0.013  0.002  0.003 -0.005            0.007                   
ctrl_cn:_:_      -0.003  0.020 -0.003  0.001 -0.007            0.011           -0.057  
optimizer (nloptwrap) convergence code: 0 (OK)
boundary (singular) fit: see ?isSingular

6.1 Full Model

all_data <- all_data %>%
  mutate(ctrial_congruency = as.numeric(as.factor(trial_congruency))-mean(as.numeric(as.factor(trial_congruency)))) %>%
  mutate(ctrial_gender = as.numeric(as.factor(trial_gender))-mean(as.numeric(as.factor(trial_gender)))) %>%
  mutate(cgender_link = scale(gender_link)) %>%
  mutate(cgender_total = scale(gender_total)) %>%
  mutate(cmorph_type = as.numeric(as.factor(morph_type))-mean(as.numeric(as.factor(morph_type))))
complex_model <- lmer(resid_rt~ctrial_congruency*ctrial_gender*cgender_total + (1|workerid) + (1|lexeme) + (1|name),data = all_data)
boundary (singular) fit: see ?isSingular
summary(complex_model)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: resid_rt ~ ctrial_congruency * ctrial_gender * cgender_total +  
    (1 | workerid) + (1 | lexeme)
   Data: all_data

REML criterion at convergence: 2129

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.5602 -0.6318 -0.1277  0.5143  7.7057 

Random effects:
 Groups   Name        Variance Std.Dev.
 workerid (Intercept) 0.06833  0.2614  
 lexeme   (Intercept) 0.01362  0.1167  
 Residual             0.10093  0.3177  
Number of obs: 2982, groups:  workerid, 152; lexeme, 20

Fixed effects:
                                                Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)                                   -1.370e-04  3.413e-02  4.764e+01  -0.004   0.9968    
ctrial_congruency                              5.971e-02  1.166e-02  2.806e+03   5.120 3.27e-07 ***
ctrial_gender                                  9.664e-03  1.166e-02  2.806e+03   0.829   0.4075    
cgender_total                                  5.441e-02  2.199e-02  1.500e+02   2.474   0.0145 *  
ctrial_congruency:ctrial_gender               -1.767e-02  2.334e-02  2.807e+03  -0.757   0.4490    
ctrial_congruency:cgender_total                1.010e-02  1.167e-02  2.807e+03   0.865   0.3870    
ctrial_gender:cgender_total                   -1.820e-02  1.168e-02  2.807e+03  -1.559   0.1191    
ctrial_congruency:ctrial_gender:cgender_total -1.689e-02  2.335e-02  2.807e+03  -0.723   0.4695    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
                 (Intr) ctrl_c ctrl_g cgndr_ ctrl_cngrncy:ct_ ctrl_cngrncy:cg_ ctrl_g:_
ctrl_cngrnc       0.000                                                                
ctrial_gndr       0.000  0.000                                                         
cgender_ttl      -0.001  0.001 -0.001                                                  
ctrl_cngrncy:ct_  0.000  0.000  0.001  0.000                                           
ctrl_cngrncy:cg_  0.001 -0.001 -0.003  0.001 -0.003                                    
ctrl_gndr:_       0.000 -0.001  0.001  0.000  0.002           -0.001                   
ctrl_cn:_:_       0.000 -0.001  0.003  0.000  0.001            0.000            0.004  

6.2 Gender Total

ideology_model <- lmer(resid_rt~ctrial_congruency*ctrial_gender*cgender_link + (1|workerid) + (1|lexeme) + (1|name), data=all_data)
boundary (singular) fit: see ?isSingular
summary(ideology_model)
Linear mixed model fit by REML. t-tests use Satterthwaite's method ['lmerModLmerTest']
Formula: resid_rt ~ ctrial_congruency * ctrial_gender * cgender_link +  
    (1 | workerid) + (1 | lexeme) + (1 | name)
   Data: all_data

REML criterion at convergence: 2129.1

Scaled residuals: 
    Min      1Q  Median      3Q     Max 
-2.5813 -0.6321 -0.1304  0.5107  7.6659 

Random effects:
 Groups   Name        Variance Std.Dev.
 workerid (Intercept) 0.06754  0.2599  
 name     (Intercept) 0.00000  0.0000  
 lexeme   (Intercept) 0.01365  0.1168  
 Residual             0.10099  0.3178  
Number of obs: 2982, groups:  workerid, 152; name, 24; lexeme, 20

Fixed effects:
                                               Estimate Std. Error         df t value Pr(>|t|)    
(Intercept)                                  -1.209e-04  3.407e-02  4.720e+01  -0.004  0.99718    
ctrial_congruency                             5.968e-02  1.167e-02  2.806e+03   5.116 3.33e-07 ***
ctrial_gender                                 9.695e-03  1.167e-02  2.806e+03   0.831  0.40607    
cgender_link                                  6.112e-02  2.184e-02  1.500e+02   2.798  0.00581 ** 
ctrial_congruency:ctrial_gender              -1.761e-02  2.334e-02  2.807e+03  -0.754  0.45070    
ctrial_congruency:cgender_link                1.229e-02  1.167e-02  2.807e+03   1.053  0.29254    
ctrial_gender:cgender_link                   -1.021e-02  1.168e-02  2.807e+03  -0.874  0.38218    
ctrial_congruency:ctrial_gender:cgender_link -6.519e-03  2.336e-02  2.807e+03  -0.279  0.78017    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Correlation of Fixed Effects:
                 (Intr) ctrl_c ctrl_g cgndr_ ctrl_cngrncy:ct_ ctrl_cngrncy:cg_ ctrl_g:_
ctrl_cngrnc       0.000                                                                
ctrial_gndr       0.000  0.000                                                         
cgender_lnk       0.000  0.001 -0.001                                                  
ctrl_cngrncy:ct_  0.000  0.000  0.001  0.000                                           
ctrl_cngrncy:cg_  0.001 -0.001 -0.002  0.001 -0.002                                    
ctrl_gndr:_       0.000 -0.001  0.000  0.000  0.002           -0.001                   
ctrl_cn:_:_       0.000  0.000  0.003  0.000  0.000            0.000            0.004  
optimizer (nloptwrap) convergence code: 0 (OK)
boundary (singular) fit: see ?isSingular

7 Comments

all_data %>%
  group_by(workerid,poli_party) %>%
  summarise(comments = paste(unique(subject_information.comments))) %>%
  select(poli_party,comments)
`summarise()` has grouped output by 'workerid'. You can override using the `.groups` argument.
Adding missing grouping variables: `workerid`

8 Testing Grounds

8.1 Checking the times

new_toy <- read.csv('maze_task_1-merged.csv') %>%
  filter(trial_id!= 'example') %>%
  filter(response_correct != 0) %>%
  mutate(trial_gender = ifelse(condition=='neutral_female' | condition == 'congruent_female','female','male')) %>%
  mutate(trial_congruency = ifelse(condition=='congruent_male' | condition == 'congruent_female','congruent','neutral'))
new_toy %>%
  group_by(word_idx,trial_gender) %>%
  summarize(MeanRT = mean(rt)) %>%
  ggplot(aes(x=word_idx, y=log(MeanRT), color=trial_gender)) + 
  geom_line() + 
  geom_point()
`summarise()` has grouped output by 'word_idx'. You can override using the `.groups` argument.

new_toy %>%
  group_by(word_idx,trial_gender) %>%
  summarize(MeanRT = mean(rt)) %>%
  ggplot(aes(x=word_idx, y=MeanRT, color=trial_gender)) + 
  geom_line() + 
  geom_point()
`summarise()` has grouped output by 'word_idx'. You can override using the `.groups` argument.

Rscript merge_results.R maze_task_1-merged.csv dems maze_task_2-merged.csv reps


  1. Part of this experiment and analysis was also carried out as part of my class project in Stanford’s LINGUIST 245B ‘Methods in Psycholinguistics’ class, taught by Judith Degen.↩︎

  2. This amounts to an hourly rate of $20.73. We originally anticipated that participants would take an average of 7 minutes to complete the experiment, and set the base pay at $15 an hour.↩︎

LS0tCnRpdGxlOiAiR2VuZGVyIElkZW9sb2dpZXMgYW5kIExhbmd1YWdlIFByb2Nlc3Npbmc6IEEgU2VsZi1QYWNlZCBSZWFkaW5nIFRpbWUgU3R1ZHkiCmF1dGhvcjogIkIuIFBhcGluZWF1IgpkYXRlOiAiMjAyMSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IG5vCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IGpvdXJuYWwKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KCiMgSW50cm9kdWN0aW9uClRoaXMgZG9jdW1lbnQgY29udGFpbnMgdGhlIHJlc3VsdHMgYW5kIGFuYWx5c2lzIG9mIG15IHNlY29uZCBleHBlcmltZW50IGZvciBteSBmaXJzdCBRdWFsaWZ5aW5nIFBhcGVyIHRvd2FyZHMgdGhlIFBoRCBpbiBMaW5ndWlzdGljcyBhdCBTdGFuZm9yZCBVbml2ZXJzaXR5XltQYXJ0IG9mIHRoaXMgZXhwZXJpbWVudCBhbmQgYW5hbHlzaXMgd2FzIGFsc28gY2FycmllZCBvdXQgYXMgcGFydCBvZiBteSBjbGFzcyBwcm9qZWN0IGluIFN0YW5mb3JkJ3MgTElOR1VJU1QgMjQ1QiAnTWV0aG9kcyBpbiBQc3ljaG9saW5ndWlzdGljcycgY2xhc3MsIHRhdWdodCBieSBKdWRpdGggRGVnZW4uXS4gCgojIE1ldGhvZHMKIyMgVGhlIEV4cGVyaW1lbnQKVGhlIGV4cGVyaW1lbnQgYW5hbHl6ZWQgaGVyZWluIHdhcyBhbiBvbmxpbmUgbWF6ZSB0YXNrIHN0dWR5LCB3aGVyZWluIHBhcnRpY2lwYW50cyByZWFkIGEgc2VudGVuY2Ugc3VjaCBhcyAiRGF2aWQgaXMgYSBjb25ncmVzc3BlcnNvbiBmcm9tIFZpcmdpbmlhLiBIZSBsaWtlcyBjeWNsaW5nLiIgRm9yIGVhY2ggb2YgdGhlIDIwIGNyaXRpY2FsIGl0ZW1zLCBwYXJ0aWNpcGFudHMgd2VyZSByYW5kb21seSBhc3NpZ25lZCB0byBvbmUgb2YgZm91ciBjb25kaXRpb25zLCB0aGUgY3JpdGljYWwgcmVnaW9ucyBvZiB3aGljaCBhcmUgZW51bWVyYXRlZCBhbmQgZXhlbXBsaWZpZWQgaGVyZToKCjxvbD4KICA8bGk+TWFsZS1jb25ncnVlbnQ6IDxpPkRhdmlkIGlzIGEgY29uZ3Jlc3NtYW48L2k+PC9saT4KICA8bGk+TWFsZS1uZXV0cmFsOiA8aT5EYXZpZCBpcyBhIGNvbmdyZXNzcGVyc29uPC9pPjwvbGk+CiAgPGxpPkZlbWFsZS1jb25ncnVlbnQ6IDxpPlNhbGx5IGlzIGEgY29uZ3Jlc3N3b21hbjwvaT48L2xpPgogIDxsaT5GZW1hbGUtbmV1dHJhbDogPGk+U2FsbHkgaXMgYSBjb25ncmVzc3BlcnNvbjwvaT48L2xpPgo8L29sPgoKUGFydGljaXBhbnRzIHByb2NlZWRlZCB0aHJvdWdoIHRoZSBzZW50ZW5jZXMgYnkgcHJlc3NpbmcgYSBrZXlib2FyZCBrZXkgd2hpY2ggY29ycmVzcG9uZGVkIHRvIHRoZSBncmFtbWF0aWNhbCBjb250aW51YXRpb24gb2YgdGhlIHNlbnRlbmNlLCBhbmQgcmVhZGluZyBwYWlyIG9mIGdyYW1tYXRpY2FsIGFuZCBkaXN0cmFjdG9yIGl0ZW1zIGF0IGEgdGltZS4gVGhleSB3ZXJlIHRoZW4gYXNrZWQgYXR0ZW50aW9uIGNoZWNrIHF1ZXN0aW9ucyBhdCB0aGUgZW5kIG9mIGVhY2ggc2VudGVuY2U7IGF0dGVudGlvbiBjaGVjayBxdWVzdGlvbnMgbmV2ZXIgZXhwbGljaXRseSBpbnZva2VkIGdlbmRlci4gUmF0aGVyLCB0aGV5IGFza2VkIGFib3V0IHRoZSBjaGFyYWN0ZXIncyBob21lIHN0YXRlcy4gRm9yIGEgaGFuZHMtb24gbG9vayBhdCB0aGUgZXhwZXJpbWVudCwgeW91IGNhbiBjbGljayA8YSBocmVmPSJodHRwczovL2JyYW5wYXAuZ2l0aHViLmlvL2dlbmRlcl9wcm9jZXNzaW5nL2V4cGVyaW1lbnRzLzJfTWF6ZV9OZXV0cmFsaXR5L2V4cGVyaW1lbnQvZXhwZXJpbWVudC5odG1sIj4gaGVyZTwvYT4gdG8gZ28gdG8gdGhlIHNhbWUgd2VicGFnZSBwYXJ0aWNwYW50cyB3ZXJlIGRpcmVjdGVkIHRvIGZvciB0aGUgdGFzay4KCiMjUGFydGljaXBhbnRzIApXZSBvcmlnaW5hbGx5IHJhbiB0aGUgZXhwZXJpbWVudCBvbiAyMDAgcGFydGljaXBhbnRzLCByZWNydWl0ZWQgdGhyb3VnaCB0aGUgb25saW5lIHBhcnRpY2lwYW50IHJlY3J1aXRtZW50IHBsYXRmb3JtIDxhIGhyZWY9Imh0dHBzOi8vd3d3LnByb2xpZmljLmNvIj5Qcm9saWZpYzwvYT4uIFRoZSBtZWFuIHRpbWUgb2YgdGhlIGV4cGVyaW1lbnQgd2FzIDUuMzkgbWludXRlcywgYW5kIHBhcnRpY2lwYW50cyB3ZXJlIHBhaWQgJDEuNzUgZm9yIHRoZWlyIHBhcnRpY2lwYXRpb25eW1RoaXMgYW1vdW50cyB0byBhbiBob3VybHkgcmF0ZSBvZiBcJDIwLjczLiBXZSBvcmlnaW5hbGx5IGFudGljaXBhdGVkIHRoYXQgcGFydGljaXBhbnRzIHdvdWxkIHRha2UgYW4gYXZlcmFnZSBvZiA3IG1pbnV0ZXMgdG8gY29tcGxldGUgdGhlIGV4cGVyaW1lbnQsIGFuZCBzZXQgdGhlIGJhc2UgcGF5IGF0IFwkMTUgYW4gaG91ci5dLiBUaGUgb25seSByZXN0cmljdGlvbnMgcGxhY2VkIG9uIHBhcnRpY2lwYW50cyB3ZXJlIHRoYXQgdGhleToKCjxvbD4KICA8bGk+V2VyZSBib3JuIGluIHRoZSBVbml0ZWQgU3RhdGVzPC9saT4KICA8bGk+TGl2ZWQgaW4gdGhlIFVuaXRlZCBTdGF0ZXMgYXQgdGhlIHRpbWUgb2YgcGFydGljaXBhdGlvbjwvbGk+CiAgPGxpPlNwb2tlIEVuZ2xpc2ggYXMgYSBmaXJzdCBsYW5ndWFnZTwvbGk+CiAgPGxpPkhhZCBub3QgcGFydGljaXBhdGVkIGluIHRoZSBub3JtaW5nIHN0dWR5IGZvciB0aGUgc3RpbXVsaTwvbGk+Cjwvb2w+CgpUaGVzZSByZXF1aXJlbWVudHMgd2VyZSBpbXBsZW1lbnRlZCBpbiBvcmRlciB0byBhc3N1cmUgdGhhdCBzcGVha2VycyBjYW1lIGZyb20gYXQgbGVhc3Qgc29tZXdoYXQgc2ltaWxhciBsaW5ndWlzdGljIGJhY2tncm91bmRzLCBhcyBjZXJ0YWluIGxleGljYWwgaXRlbXMgaW4gdGhlIHN0dWR5IChzdWNoIGFzIDxpPmNvbmdyZXNzcGVyc29uPC9pPikgYXJlIHF1aXRlIGxvY2FsaXplZCB0byB0aGUgVW5pdGVkIFN0YXRlcy4KCkFmdGVyIHRoaXMgaW5pdGlhbCBydW4gb2YgdGhlIGV4cGVyaW1lbnQsIHdlIGZvdW5kIHRoYXQgdGhlcmUgd2FzIGEgZGVhcnRoIG9mIGNvbnNlcnZhdGl2ZSBvciBSZXB1YmxpY2FuLWFsaWduZWQgcGFydGljaXBhbnRzLiBBcyBhIHJlc3VsdCwgd2UgcmFuIHRoZSBleHBlcmltZW50IGFnYWluLCB0aGlzIHRpbWUgb24gOTggc2VsZi1pZGVudGlmaWVkIFJlcHVibGljYW5zLiBUaGlzIHdhcyBhY2hpZXZlZCBieSBhZGRpbmcgYSBmaWx0ZXIgb24gUHJvbGlmaWMgc28gdGhhdCBvbmx5IFJlcHVibGljYW4taWRlbnRpZmllZCBpbmRpdmlkdWFscyBjb3VsZCBzZWUgdGhlIHRhc2suIFRoZSByZXN0IG9mIHRoZSBleHBlcmltZW50LCBpbmNsdWRpbmcgcGF5bWVudCwgd2FzIGV4YWN0bHkgdGhlIHNhbWUsIGV4Y2VwdCB0aGF0IGFuIGFkZGl0aW9uYWwgZGlzY2xhaW1lciB0aGF0IHBhcnRpY2lwYW50cyBjb3VsZCBub3QgdXNlIHRoZSBGaXJlRm94IGJyb3dzZXIgZXhwZXJpbWVudCwgYWZ0ZXIgdGhlIGZpcnN0IHJ1biByZXZlYWxlZCBhbiBpbmNvbXBhdGliaWxpdHkgYmV0d2VlbiBKYXZhU2NyaXB0IGFuZCBGaXJlRm94LiBUaGUgdHdvIHJ1bnMgb2YgdGhlIGV4cGVyaW1lbnQgYW1vdW50ZWQgaW4gYSB0b3RhbCBvZiAyOTggcGFydGljaXBhbnRzIHdobyBjb21wbGV0ZWQgdGhlIHRhc2suCgojIFByZXBwaW5nIHRoZSBEYXRhCkJlZm9yZSB3ZSBjYW4gZG8gbXVjaCBvZiBhbnl0aGluZyB3aXRoIHRoZSBkYXRhLCB3ZSBuZWVkIHRvIG1ha2Ugc3VyZSBpdCdzIHVzYWJsZSEgVGhpcyBtZWFucyBmaWx0ZXJpbmcgb3V0IGFsbCB1bmltcG9ydGFudCBvciBleHRyYW5lb3VzIHRyaWFscywgcnVubmluZyBleGNsdXNpb24gY3JpdGVyaWEsIGFuZCBhZGRpbmcgYWRkaXRpb25hbCB0cmlhbCBhbmQgaXRlbS1sZXZlbCBkYXRhIHRoYXQgd2lsbCBiZSBuZWNlc3NhcnkgbGF0ZXIgaW4gdGhlIGFuYWx5c2lzLgoKIyMgUGFja2FnZXMKRm9yIHRoaXMgYW5hbHlzaXMsIHdlIHJlcXVpcmUgdGhlIGZvbGxvd2luZyBwYWNrYWdlczoKCmBgYHtyIGVjaG89VFJVRX0KbGlicmFyeShnZ3Bsb3QyKSAKbGlicmFyeSh0aWR5dmVyc2UpIApsaWJyYXJ5KGxtZTQpIApsaWJyYXJ5KHN0cmluZ3IpCmxpYnJhcnkobGFuZ3VhZ2VSKQpsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KHJlc2hhcGUyKQoKc291cmNlKCJoZWxwZXJzLlIiKQpgYGAKCiMjIFJlYWRpbmcgaW4gdGhlIERhdGEKSW4gdGhlIGZpcnN0IGluc3RhbmNlLCB3ZSBuZWVkIHRvIHJlYWQgaW4gdGhlIGRhdGEsIHdoaWNoIGhhcyBiZWVuIHByZS1tZXJnZWQgZnJvbSBib3RoIHJ1bnMgb2YgdGhlIGV4cGVyaW1lbnQuIFdlIHdpbGwgYWxzbyBpbiB0aGlzIGNodW5rIGZpbHRlciBvdXQgYWxsIG9mIHRoZSBleGFtcGxlIHRyaWFscywgYXMgd2VsbCBhcyBhbGwgdGhlIGRhdGEgcG9pbnRzIHRoYXQgYXJlIGZyb20gbm9uLWNyaXRpY2FsIHRyaWFscy4gCgpgYGB7cn0KYWxsX2RhdGEgPC0gcmVhZC5jc3YoJ21lcmdlZF9hbGwuY3N2JykgJT4lCiAgZmlsdGVyKHRyaWFsX2lkIT0gJ2V4YW1wbGUnKSAlPiUKICBmaWx0ZXIocmVnaW9uPT0nY3JpdGljYWwnKQpgYGAKCiMjIFJ1bm5pbmcgRXhjbHVzaW9uIENyaXRlcmlhCk5vdywgd2Ugd2FudCB0byBleGNsdWRlIGFueSBwYXJ0aWNpcGFudHMgd2hvIGZhaWxlZCB0byBhbnN3ZXIgYXQgbGVhc3QgODUlIG9mIHRoZSBhdHRlbnRpb24gY2hlY2sgcXVlc3Rpb25zIGNvcnJlY3RseS4gV2UgZG8gdGhpcyBieSBjcmVhdGluZyBhIGxpc3Qgb2YgYWxsIHBhcnRpY2lwYW50cyB3aG8gc2NvcmVkIGxlc3MgdGhhbiA4NSUgb24gdGhlc2UgY2hlY2tzLCBhbmQgdGhlbiBjcm9zcy1yZWZlcmVuY2luZyB0aGlzIGxpc3Qgd2l0aCBhbGwgZGF0YSBwb2ludHMsIHJlbW92aW5nIGFueSBkYXRhIHBvaW50cyB3aG9zZSBwYXJ0aWNpcGFudHMgd2VyZSBpbiB0aGUgZXhjbHVzaW9uIGxpc3QuIAoKYGBge3J9CmV4Y2x1c2lvbiA8LSBhbGxfZGF0YSAlPiUgZ3JvdXBfYnkod29ya2VyaWQpICU+JQogIHN1bW1hcmlzZShhY2N1cmFjeSA9IG1lYW4ocmVzcG9uc2VfY29ycmVjdCkpICU+JQogIG11dGF0ZShleGNsdWRlID0gaWZlbHNlKGFjY3VyYWN5IDwgMC44NSwnWWVzJywnTm8nKSkgJT4lIAogIGZpbHRlcihleGNsdWRlID09ICdZZXMnKQoKYWxsX2RhdGEgPC0gYWxsX2RhdGFbIShhbGxfZGF0YSR3b3JrZXJpZCAlaW4lIGV4Y2x1c2lvbiR3b3JrZXJpZCksXSAlPiUKICBmaWx0ZXIocnQgIT0nbnVsbCcpCmBgYAoKV2UgYWxzbyB3YW50IHRvIGZpbHRlciBvdXQgYWxsIHRyaWFscyBpbiB3aGljaCB0aGUgcmVhZGluZyB0aW1lIGZvciB0aGUgY3JpdGljYWwgaXRlbSB3YXMgbW9yZSB0aGFuIDIuNSBzdGFuZGFyZCBkZXZpYXRpb25zIGZyb20gdGhlIG1lYW4gcmVhZGluZyB0aW1lIG9uIHRoYXQgbGV4aWNhbCBpdGVtIGFjcm9zcyBhbGwgcGFydGljaXBhbnRzLiAKCgoKCmFsbF9kYXRhIDwtIGFsbF9kYXRhICU+JQogIGdyb3VwX2J5KHRyaWFsX2lkKSAlPiUKICBtdXRhdGUoaWRfbWVhbiA9IG1lYW4obG9nKHJ0KSkpICU+JQogIG11dGF0ZShleGNsdXNpb24gPSAobG9nKHJ0KSA8IG1lYW4obG9nKHJ0KSkgLSAyKnNkKGxvZyhydCkpfChsb2cocnQpID4gbWVhbihsb2cocnQpKSArIDIqc2QobG9nKHJ0KSkpKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIGZpbHRlcihleGNsdXNpb249PUZBTFNFKQoKCgpUaGlzIHJlc3VsdHMgaW4gMjM4IHRyaWFscyBiZWluZyByZW1vdmVkIGZyb20gdGhlIDU1ODAgd2UgZ290IGFmdGVyIHRoZSBieS1wYXJ0aWNpcGFudCBleGNsdXNpb25zLiBXZSBub3cgaGF2ZSA1MzQyIHRyaWFscyB3ZSBjYW4gdXNlIGZvciBhbmFseXNpcy4KCiMjIEFkZGluZyBpbiBBZGRpdGlvbmFsIEltcG9ydGFudCBUcmlhbCBJbmZvcm1hdGlvbiB7LnRhYnNldH0KTm93IHRoYXQgd2UgaGF2ZSBvbmx5IHRoZSByb3dzIHdlIHdhbnQsIGxldCdzIGFkZCBzb21lIG5ldyBjb2x1bW5zLCB3aGljaCB3aWxsIGNvbnRhaW4gaW1wb3J0YW50IGluZm9ybWF0aW9uIGZvciBlYWNoIGRhdGEgcG9pbnQuIEhlcmUsIHdlIHdpbGwgYmUgYWRkaW5nOgoKLSBHZW5kZXIgSWRlb2xvZ3kgU3Vic2NvcmVzCi0gVHJpYWwgR2VuZGVycwotIFRyaWFsIE1vcnBob2xvZ3kgVHlwZXMKLSBDcml0aWNhbCBJdGVtIExlbmd0aCAmIExlbmd0aC1Db250cm9sbGVkIFJlc2lkdWFscwotIFRyaWFsIENvbmdydWVuY3kgCi0gUGFydGlwYW50IFBvbGl0aWNhbCBBZmZpbGlhdGlvbgoKSWRlYWxseSwgSSB3b3VsZCd2ZSBhZGRlZCBhbGwgb2YgdGhlc2UgYnV0IHRoZSBmaXJzdCB3aGVuIEkgYWN0dWFsbHkgY3JlYXRlZCB0aGUgc3RpbXVsaSBhbmQgbG9nZ2VkIHJlc3BvbnNlcywgYnV0IEkgZm9yZ290IHRvISBMdWNraWx5LCBSIGFsbG93cyB1cyB0byBkbyB0aGlzIHBvc3QtaG9jIGZhaXJseSBzdHJhaWdodGZvcndhcmRseS4uLiB3aGljaCBpcyBnb29kLCBzaW5jZSB0aGVzZSBmZWF0dXJlcyB3aWxsIGJlIGNyaXRpY2FsIGluIG91ciBkYXRhIHZpc3VhbGl6YXRpb24gYW5kIGFuYWx5c2lzLjxicj4KPGJyPgoKIyMjIERlZmluaW5nIEdlbmRlciBTdWJzY29yZXMKPGJyPgpUaGUgcXVlc3Rpb24gdW5kZXIgaW52ZXN0aWdhdGlvbiBoZXJlIGlzIHdoZXRoZXIgb3Igbm90IGluZGl2aWR1YWxzJyBjb25jZXB0aW9ucyBvZiBnZW5kZXIgYWZmZWN0IGhvdyB0aGV5IHByb2Nlc3MgIGdlbmRlcmVkIGFuZCBnZW5kZXItbmV1dHJhbCBmb3JtcyBvZiBFbmdsaXNoIHBlcnNvbmFsIGFuZCBwcm9mZXNzaW9uYWwgdGl0bGVzLiA8YnI+Cjxicj4KSW4gb3JkZXIgdG8gZXhhbWluZSB0aGlzLCB3ZSBuZWVkIHRvIHF1YW5pZnkgcGFydGljaXBhbnRzJyBpZGVvbG9naWNhbCB2aWV3cyEgSGVyZSB3ZSBoYXZlIGFkb3B0ZWQgdGhlIDEzLWl0ZW0gU29jaWFsIFJvbGVzIFF1ZXN0aW9ubmFpcmUgcHV0IGZvcnRoIGluIEJhYmVyICYgVHVja2VyICgyMDA2KS4gUXVlc3Rpb25zIDEtNSBjb3JyZWxhdGUgdG8gdGhlIDxpPidHZW5kZXIgVHJhbnNjZW5kZW50JzwvaT4gc3Vic2NhbGUsIGFuZCBxdWVzdGlvbnMgNi0xMyBjb3JyZXNwb25kIHRvIHRoZSA8aT4nR2VuZGVyIExpbmtlZCc8L2k+IHN1YnNjYWxlLiBFYWNoIGl0ZW0gaXMgc2NvcmVkIG9uIGEgc2NhbGUgb2YgMC0xMDAuIFNvLCB0aGUgZmlyc3QgdGhpbmcgd2Ugd2FudCB0byBkbyBpcyBtYWtlIHR3byBsaXN0cyBvZiBjb2x1bW5zIHdoaWNoIGNvcnJlc3BvbmQgdG8gdGhlc2UgdHdvIHN1YnNjYWxlcywgc2luY2UgdGhlIHF1ZXN0aW9ucyBhcmUgc3RvcmVkIGluZGl2aWR1YWxseSBpbiB0aGUgZGF0YToKCmBgYHtyfQpnZW5kZXJfdHJhbnNjZW5kZW5jZV9jb2xzIDwtIGMoJ3N1YmplY3RfaW5mb3JtYXRpb24uZ2VuZGVyX3ExJywnc3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXJfcTInLCdzdWJqZWN0X2luZm9ybWF0aW9uLmdlbmRlcl9xMycsJ3N1YmplY3RfaW5mb3JtYXRpb24uZ2VuZGVyX3E0Jywnc3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXJfcTUnKQoKZ2VuZGVyX2xpbmtlZF9jb2xzIDwtIGMoJ3N1YmplY3RfaW5mb3JtYXRpb24uZ2VuZGVyX3E2Jywnc3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXJfcTcnLCdzdWJqZWN0X2luZm9ybWF0aW9uLmdlbmRlcl9xOCcsJ3N1YmplY3RfaW5mb3JtYXRpb24uZ2VuZGVyX3E5Jywnc3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXJfcTEwJywnc3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXJfcTExJywnc3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXJfcTEyJywnc3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXJfcTEzJykKYGBgCjxicj4KTm93IHdlIGNhbiB1c2UgdGhlIG11dGF0ZSgpIG1ldGhvZCBvbiA8Yj5hbGxfZGF0YTwvYj4gdG8gYWRkIHR3byBuZXcgY29sdW1ucywgb25lIGZvciBlYWNoIHN1YnNjYWxlLiBXZSB0ZWxsIFIgdG8gdGFrZSB0aGUgbWVhbnMgb2YgdGhlIHNwZWNpZmllZCBjb2x1bW5zIGluIFtjb2x1bW5fbmFtZXNdIG9mIDxiPmFsbF9kYXRhPC9iPiBmb3IgZWFjaCBpbmRpdmlkdWFsIHJvdzogcm93TWVhbnMoYWxsX2RhdGFbY29sdW1uX25hbWVzXSkuIFdlIGFsc28gaGF2ZSB0byBzdWJ0cmFjdCB0aGlzIG1lYW4gZnJvbSAxMDAgaW4gdGhlIGNhc2Ugb2YgdGhlIDxpPidHZW5kZXIgVHJhbnNjZW5kZW50JzwvaT4gc3Vic2NhbGUsIHNpbmNlIGl0IGlzIGludmVyc2VseSBzY29yZWQuIEZpbmFsbHksIHdlIGNhbiBjcmVhdGUgYW4gYXZlcmFnZSB0b3RhbCBzY29yZSByZWdhcmRsZXNzIG9mIHN1YnNjb3Jlcywgc2ltcGx5IGJ5IG1lYW5pbmcgdGhlIHR3byBzdWJzY29yZXMgd2UgYWxyZWFkeSBoYXZlLgoKYGBge3J9CmFsbF9kYXRhIDwtIGFsbF9kYXRhICU+JQogIG11dGF0ZShnZW5kZXJfdHJhbnMgPSAxMDAgLSAocm93TWVhbnMoYWxsX2RhdGFbZ2VuZGVyX3RyYW5zY2VuZGVuY2VfY29sc10pKSkgJT4lCiAgbXV0YXRlKGdlbmRlcl9saW5rID0gcm93TWVhbnMoYWxsX2RhdGFbZ2VuZGVyX2xpbmtlZF9jb2xzXSkpIAoKZ2VuZGVyX2FsbCA9IGMoJ2dlbmRlcl90cmFucycsJ2dlbmRlcl9saW5rJykKCmFsbF9kYXRhIDwtIGFsbF9kYXRhICU+JQogIG11dGF0ZShnZW5kZXJfdG90YWwgPSByb3dNZWFucyhhbGxfZGF0YVtnZW5kZXJfYWxsXSkpCmBgYAoKCiMjIyBBZGRpbmcgR2VuZGVyCjxicj4KV2UgYWxzbyB3YW50IHRvIGFkZCB3aGV0aGVyIHRoZSB0cmlhbCBpbmNsdWRlZCBhIGZlbWFsZSBvciBtYWxlIHJlZmVyZW50IChidXQgYWxzbywgbGlrZSwgZGVzdHJveSB0aGUgYmluYXJ5ISkuIEluIG9yZGVyIHRvIGRvIHRoaXMsIHdlJ2xsIGp1c3QgYWRkIGEgPGI+dHJpYWxfZ2VuZGVyPC9iPiBjb2x1bW4gdGhhdCBzYXlzIDxpPidmZW1hbGUnPC9pPiBpZiB0aGUgY29uZGl0aW9uIHdhcyBlaXRoZXIgPGk+J25ldXRyYWxfZmVtYWxlJzwvaT4gb3IgPGk+J2NvbmdydWVudF9mZW1hbGUnPC9pPi4gT3RoZXJ3aXNlLCB3ZSB3YW50IHRoZSA8Yj50cmlhbF9nZW5kZXI8L2I+IHRvIHNheSA8aT4nbWFsZSc8L2k+LgoKYGBge3J9CmFsbF9kYXRhIDwtIGFsbF9kYXRhICU+JQogIG11dGF0ZSh0cmlhbF9nZW5kZXIgPSBpZmVsc2UoY29uZGl0aW9uPT0nbmV1dHJhbF9mZW1hbGUnIHwgY29uZGl0aW9uID09ICdjb25ncnVlbnRfZmVtYWxlJywnZmVtYWxlJywnbWFsZScpKQoKYWxsX2RhdGEgJT4lCiAgc2VsZWN0KHdvcmtlcmlkLHJ0LGNvbmRpdGlvbix0cmlhbF9pZCx0cmlhbF9nZW5kZXIpCmBgYAoKIyMjIEFkZGluZyBNb3JwaG9sb2d5IFR5cGUKPGJyPgpOb3cgd2Ugd2FudCB0byBhZGQgd2hldGhlciBvciBub3QgdGhlIGxleGVtZSdzIG5ldXRyYWwgZm9ybSBpcyBkZXZlbG9wZWQgYnkgY29tcG91bmRpbmcgKGFzIGluIDxpPidjb25ncmVzcy1wZXJzb24nPC9pPikgb3IgYnkgdGhlIGFkb3B0aW9uIG9mIHRoZSBtYWxlIGZvcm0gKGFzIGluIDxpPidhY3Rvcic8L2k+IGJlaW5nIHVzZWQgbW9yZSBmb3IgYm90aCBtZW4gYW5kIHdvbWVuKS4gSW4gdGhpcyBzdHVkeSwgd2Ugb25seSBoYXZlIHNpeCBsZXhlbWVzIG9mIHRoZSBsYXR0ZXIgdHlwZSwgc28gd2UnbGwganVzdCB0ZWxsIFIgdG8gYXNzaWduIHRob3NlIGEgPGI+bW9ycGhfdHlwZTwvYj4gdmFsdWUgb2YgPGk+J2Fkb3B0aW9uJzwvaT4gKGZvciAnbWFsZSBhZG9wdGlvbicpLCBhbmQgYWxsIGVsc2Ugd2lsbCBiZSBhc3NpZ25lZCBhIHZhbHVlIG9mIDxpPidjb21wb3VuZCc8L2k+LgoKYGBge3J9CmFsbF9kYXRhIDwtIGFsbF9kYXRhJT4lCiAgbXV0YXRlKG1vcnBoX3R5cGUgPSBpZmVsc2UobGV4ZW1lIT0gJ2FjdG9yJyAmIGxleGVtZSE9ICdob3N0JyAmIGxleGVtZSAhPSdodW50ZXInICYgbGV4ZW1lIT0gJ3ZpbGxhaW4nICYgbGV4ZW1lIT0gJ2hlaXInICYgbGV4ZW1lIT0gJ2hlcm8nLCdjb21wb3VuZCcsJ2Fkb3B0aW9uJykpCgphbGxfZGF0YSAlPiUKICBzZWxlY3QocnQsbGV4ZW1lLG1vcnBoX3R5cGUpCmBgYAoKCiMjIyBBZGRpbmcgRm9ybSBMZW5ndGggJiBMZW5ndGgtQ29udHJvbGxlZCBSZXNpZHVhbHMKPGJyPgpBbm90aGVyIGltcG9ydGFudCBmYWN0b3Igd2Ugd2FudCB0byBleHBsb3JlIGlzIHRoZSBsZW5ndGggb2YgdGhlIGNyaXRpY2FsIGl0ZW0hIEluIG9yZGVyIHRvIGFkZCB0aGlzLCB3ZSBzaW1wbHkgY3JlYXRlIGEgbmV3IGNvbHVtbiA8Yj5mb3JtX2xlbmd0aDwvYj4gYW5kIHRlbGwgUiB0byBpbnB1dCBhcyB0aGF0IGNvbHVtbidzIHZhbHVlIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyB0aGF0IGFwcGVhcnMgaW4gdGhhdCByb3cncyA8Yj5mb3JtPC9iPiBjb2x1bW4sIHdoaWNoIGNvcnJlc3BvbmRzIHRvIHRoZSBvcnRob2dyYXBpYyBmb3JtIG9mIHRoZSBjcml0aWNhbCBpdGVtIGluIHRoYXQgdHJpYWwuIDxpPk5vdGUgdGhhdCB0aGlzIHdpbGwgaW5jbHVkZSBzcGFjZXMgaW4gdGhlIGNvdW50ITwvaT4KCmBgYHtyfQphbGxfZGF0YSA8LSBhbGxfZGF0YSAlPiUKICBtdXRhdGUoZm9ybV9sZW5ndGggPSBzdHJfbGVuZ3RoKGZvcm0pKQoKc2ltcGxlX21vZGVsIDwtIGxtKGxvZyhydCl+Zm9ybV9sZW5ndGgsIGRhdGEgPSBhbGxfZGF0YSkKCmFsbF9kYXRhIDwtIGFsbF9kYXRhICU+JQogIG11dGF0ZShyZXNpZF9ydCA9IHJlc2lkKHNpbXBsZV9tb2RlbCkpCmBgYAoKYGBge3J9CnN1bW1hcnkoc2ltcGxlX21vZGVsKQpgYGAKCgpOb3cgdGhhdCB3ZSBoYXZlIHRoZXNlLCB3ZSBjYW4gcnVuIGEgc2ltcGxlIGxpbmVhciByZWdyZXNzaW9uIHdoaWNoIHdpbGwgc2hvdyB1cyB0aGUgZWZmZWN0IG9mIG9ydGhvZ3JhcGhpYyBsZW5ndGggb24gcmVhZGluZyB0aW1lLiBUaGVuIHdlIGFkZCBhIG5ldyBjb2x1bW4gaW4gdGhlIGRhdGEgd2hpY2ggaXMgdGhlIHJlc2lkdWFsIHJlYWRpbmcgdGltZSwgb3IgdGhlIHJlYWRpbmcgdGltZSBpbiBsb2cgc3BhY2UgQUZURVIgd2UgY29udHJvbCBmb3IgdGhlIGVmZmVjdHMgb2Ygb3J0aG9ncmFwaGljIGxlbmd0aC4KCiMjIyBBZGRpbmcgQ29uZ3J1ZW5jeSBDb2x1bW4KPGJyPgpXZSBhbHNvIHdhbnQgdG8gbWFrZSBzdXJlIHdlIGhhdmUgYSBjb2x1bW4gd2hpY2ggcmVjb3JkcyB3aGV0aGVyIG9yIG5vdCB0aGUgdHJpYWwgd2FzIGdlbmRlci1jb25ncnVlbnQgKGFzIGluIDxpPidTaGVsYnkgaXMgYSBjb25ncmVzc3dvbWFuJzwvaT4pIG9yIGdlbmRlciBuZXV0cmFsIChhcyBpbiA8aT4nU2hlbGJ5IGlzIGEgY29uZ3Jlc3NwZXJzb24nPC9pPikuIFdlIGFkZCBhIDxiPnRyaWFsX2NvbmdydWVuY3k8L2I+IGNvbHVtbiwgd2hpY2ggaXMgdmFsdWVkIGFzIDxpPidjb25ncnVlbnQnPC9pPiBpZiB0aGF0IHJvdydzIGNvbmRpdGlvbiBpcyBvbmUgb2YgdGhlIHR3byBjb25ncnVlbnQgY29uZGl0aW9ucy4gT3RoZXJ3aXNlLCBpdCBnZXRzIHZhbHVlZCBhcyA8aT4nbmV1dHJhbCc8L2k+LgoKYGBge3J9CmFsbF9kYXRhIDwtIGFsbF9kYXRhICU+JQogIG11dGF0ZSh0cmlhbF9jb25ncnVlbmN5ID0gaWZlbHNlKGNvbmRpdGlvbj09J2NvbmdydWVudF9tYWxlJyB8IGNvbmRpdGlvbiA9PSAnY29uZ3J1ZW50X2ZlbWFsZScsJ2NvbmdydWVudCcsJ25ldXRyYWwnKSkKYGBgCgojIyMgQWRkaW5nIExhcmdlIFBvbGl0aWNhbCBNYWNyb2NhdGVnb3JpZXMKPGJyPgpGaW5hbGx5LCB3ZSBjYW4gY2xhc3NpZnkgcGFydGljaXBhbnRzIGJ5IHRoZWlyIHBhcnRpY3VsYXIgcG9saXRpY2FsIGFsaWdubWVudDsgd2UgY2FuIGNvbnN0cnVlIHRoaXMgYnJvYWRseSBhcyAiUmVwdWJsaWNhbnMiIHZzLiAiRGVtb2NyYXRzIiwgd2l0aCB0aG9zZSB3aG8gZGVjbGluZWQgdG8gc3RhdGUgYSBwcmVmZXJlbmNlLCBvciBwbGFjZWQgdGhlbXNlbHZlcyBpbiB0aGUgbWlkZGxlLCBhcyAiTm9uLVBhcnRpc2FuIi4KCmBgYHtyfQphbGxfZGF0YSA8LSBhbGxfZGF0YSAlPiUKICBtdXRhdGUocG9saV9wYXJ0eSA9IGlmZWxzZShzdWJqZWN0X2luZm9ybWF0aW9uLnBhcnR5X2FsaWdubWVudCA9PSAxIHwgc3ViamVjdF9pbmZvcm1hdGlvbi5wYXJ0eV9hbGlnbm1lbnQgPT0gMiwnUmVwdWJsaWNhbicsaWZlbHNlKHN1YmplY3RfaW5mb3JtYXRpb24ucGFydHlfYWxpZ25tZW50ID09IDQgfCBzdWJqZWN0X2luZm9ybWF0aW9uLnBhcnR5X2FsaWdubWVudCA9PSA1LCdEZW1vY3JhdCcsJ05vbi1QYXJ0aXNhbicpKSkKYGBgCgojIERhdGEgVmlzdWFsaXphdGlvbgpOb3cgd2UgY2FuIHN0YXJ0IGFuYWx5c2luZyB0aGUgZGF0YSBieSBtZWFucyBvZiBkYXRhIHZpc3VhbGl6YXRpb24uIAoKYGBge3J9CmluYXVndXJhdGlvbl8yMDIxID0gYygiIzU0NDViMSIsICIjNzQ5ZGFlIiwgIiNmM2M0ODMiLCAiIzVjMWEzMyIsICIjY2QzMzQxIiwiI2Y3ZGM2YSIpCmBgYAoKCiMjIElkZW9sb2d5IGJ5IEFnZQoKYGBge3J9CmdncGxvdChhbGxfZGF0YSwgYWVzKHg9c3ViamVjdF9pbmZvcm1hdGlvbi5hZ2UsIHk9Z2VuZGVyX3RvdGFsKSkgKyAKICBnZW9tX3BvaW50KGFscGhhPS41KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNpemU9MS4yKQpgYGAKCiMjIFJlYWRpbmcgVGltZSBieSBHZW5kZXIgSWRlb2xvZ3kKCmBgYHtyfQpnZ3Bsb3QoYWxsX2RhdGEsIGFlcyh4PWdlbmRlcl90b3RhbCwgeT1yZXNpZF9ydCwgY29sb3I9dHJpYWxfY29uZ3J1ZW5jeSkpICsgCiAgZ2VvbV9wb2ludChhbHBoYT0uNSkgKyAKICBnZW9tX3Ntb290aChtZXRob2QgPSAnbG0nLCBzaXplPTEuMikgKyAKICB0aGVtZV9taW5pbWFsKCkKYGBgCgojIyBSZWFkaW5nIFRpbWUgYnkgQWdlCmBgYHtyfQpnZ3Bsb3QoYWxsX2RhdGEsIGFlcyh4PXN1YmplY3RfaW5mb3JtYXRpb24uYWdlLCB5PXJlc2lkX3J0LCBjb2xvcj10cmlhbF9jb25ncnVlbmN5LCBsaW5ldHlwZT1tb3JwaF90eXBlKSkgKyAKICBnZW9tX3BvaW50KGFscGhhPS41KSArIAogIGdlb21fc21vb3RoKG1ldGhvZCA9ICdsbScsIHNpemU9MS4yKQpgYGAKCiMjIFJlYWRpbmcgVGltZSBieSBDb25ncnVlbmN5IGFuZCBHZW5kZXIKCmBgYHtyfQphZ2dfc3BlYWtlcl9tZWFuX2NvbiA8LSBhbGxfZGF0YSAlPiUKICBncm91cF9ieShjb25kaXRpb24sd29ya2VyaWQpICU+JQogIHN1bW1hcml6ZShNZWFuUlQ9bWVhbihyZXNpZF9ydCkpCmBgYAoKYGBge3J9CmFsbF9kYXRhICU+JQogIGdyb3VwX2J5KGNvbmRpdGlvbix0cmlhbF9nZW5kZXIpICU+JQogIHN1bW1hcml6ZShNZWFuUlQgPSBtZWFuKHJlc2lkX3J0KSwgQ0kuTG93ID0gY2kubG93KHJlc2lkX3J0KSwgQ0kuSGlnaCA9IGNpLmhpZ2gocmVzaWRfcnQpKSAlPiUKICBtdXRhdGUoWU1pbiA9IE1lYW5SVCAtIENJLkxvdywgWU1heCA9IE1lYW5SVCArIENJLkhpZ2gpICU+JQogIGdncGxvdChhZXMoeD1jb25kaXRpb24seT1NZWFuUlQsY29sb3I9dHJpYWxfZ2VuZGVyKSkgKyAKICBnZW9tX3BvaW50KHNpemU9MykgKyAKICBnZW9tX2ppdHRlcihkYXRhID0gYWdnX3NwZWFrZXJfbWVhbl9jb24sIGFlcyh5PU1lYW5SVCksYWxwaGE9LjEsY29sb3I9J2RhcmtyZWQnKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49WU1pbix5bWF4PVlNYXgpLCB3aWR0aD0uMjUpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGluYXVndXJhdGlvbl8yMDIxKSArIAogIHRoZW1lX21pbmltYWwoKQpgYGAKIyMgUmVhZGluZyBUaW1lIGJ5IENvbmdydWVuY3ksIEdlbmRlciwgYW5kIExleGljYWwgSXRlbQoKYGBge3J9CmFsbF9kYXRhICU+JQogIGdyb3VwX2J5KGNvbmRpdGlvbix0cmlhbF9nZW5kZXIsdHJpYWxfY29uZ3J1ZW5jeSxsZXhlbWUpICU+JQogIHN1bW1hcml6ZShNZWFuUlQgPSBtZWFuKHJlc2lkX3J0KSwgQ0kuTG93ID0gY2kubG93KHJlc2lkX3J0KSwgQ0kuSGlnaCA9IGNpLmhpZ2gocmVzaWRfcnQpKSAlPiUKICBtdXRhdGUoWU1pbiA9IE1lYW5SVCAtIENJLkxvdywgWU1heCA9IE1lYW5SVCArIENJLkhpZ2gpICU+JQogIGdncGxvdChhZXMoeD1jb25kaXRpb24seT1NZWFuUlQsY29sb3I9dHJpYWxfZ2VuZGVyLHNoYXBlPXRyaWFsX2NvbmdydWVuY3kpKSArIAogIGdlb21fcG9pbnQoc2l6ZT0zKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1ZTWluLHltYXg9WU1heCksIHdpZHRoPS4yNSkgKyAKICBmYWNldF93cmFwKH4gbGV4ZW1lKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAuNywgaGp1c3Q9LjcpKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBpbmF1Z3VyYXRpb25fMjAyMSkgKyAKICBmYWNldF93cmFwKH5sZXhlbWUpCmBgYAojIyMgTWFsZSBBZG9wdGlvbnMgT25seQoKYGBge3J9CmFsbF9kYXRhICU+JQogIGZpbHRlcihtb3JwaF90eXBlID09ICJhZG9wdGlvbiIpICU+JQogIGdyb3VwX2J5KGNvbmRpdGlvbix0cmlhbF9nZW5kZXIsdHJpYWxfY29uZ3J1ZW5jeSxsZXhlbWUpICU+JQogIHN1bW1hcml6ZShNZWFuUlQgPSBtZWFuKHJlc2lkX3J0KSwgQ0kuTG93ID0gY2kubG93KHJlc2lkX3J0KSwgQ0kuSGlnaCA9IGNpLmhpZ2gocmVzaWRfcnQpKSAlPiUKICBtdXRhdGUoWU1pbiA9IE1lYW5SVCAtIENJLkxvdywgWU1heCA9IE1lYW5SVCArIENJLkhpZ2gpICU+JQogIGdncGxvdChhZXMoeD1jb25kaXRpb24seT1NZWFuUlQsY29sb3I9dHJpYWxfZ2VuZGVyLHNoYXBlPXRyaWFsX2NvbmdydWVuY3kpKSArIAogIGdlb21fcG9pbnQoc2l6ZT0zKSArCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1ZTWluLHltYXg9WU1heCksIHdpZHRoPS4yNSkgKyAKICBmYWNldF93cmFwKH4gbGV4ZW1lKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAuNywgaGp1c3Q9LjcpKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBpbmF1Z3VyYXRpb25fMjAyMSkgKyAKICBmYWNldF93cmFwKH5sZXhlbWUpCmBgYAoKIyMjIENvbXBvdW5kcyBvbmx5CgpgYGB7cn0KYWxsX2RhdGEgJT4lCiAgZmlsdGVyKG1vcnBoX3R5cGUgPT0gImNvbXBvdW5kIikgJT4lCiAgZ3JvdXBfYnkoY29uZGl0aW9uLHRyaWFsX2dlbmRlcix0cmlhbF9jb25ncnVlbmN5LGxleGVtZSkgJT4lCiAgc3VtbWFyaXplKE1lYW5SVCA9IG1lYW4ocmVzaWRfcnQpLCBDSS5Mb3cgPSBjaS5sb3cocmVzaWRfcnQpLCBDSS5IaWdoID0gY2kuaGlnaChyZXNpZF9ydCkpICU+JQogIG11dGF0ZShZTWluID0gTWVhblJUIC0gQ0kuTG93LCBZTWF4ID0gTWVhblJUICsgQ0kuSGlnaCkgJT4lCiAgZ2dwbG90KGFlcyh4PWNvbmRpdGlvbix5PU1lYW5SVCxjb2xvcj10cmlhbF9nZW5kZXIsc2hhcGU9dHJpYWxfY29uZ3J1ZW5jeSkpICsgCiAgZ2VvbV9wb2ludChzaXplPTMpICsKICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVlNaW4seW1heD1ZTWF4KSwgd2lkdGg9LjI1KSArIAogIGZhY2V0X3dyYXAofiBsZXhlbWUpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCB2anVzdCA9IC43LCBoanVzdD0uNykpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGluYXVndXJhdGlvbl8yMDIxKSArIAogIGZhY2V0X3dyYXAofmxleGVtZSkKYGBgCgojIyBSYXcgUmVhZGluZyBUaW1lIGJ5IFRyaWFsIEdlbmRlcgoKCmBgYHtyfQp0ZW1wIDwtIGFsbF9kYXRhICU+JQogIGdyb3VwX2J5KHRyaWFsX2dlbmRlcikgJT4lCiAgc3VtbWFyaXplKE1lYW5SVCA9IG1lYW4ocnQpLCBDSS5Mb3cgPSBjaS5sb3cocnQpLCBDSS5IaWdoID0gY2kuaGlnaChydCkpICU+JQogIG11dGF0ZShZTWluID0gTWVhblJUIC0gQ0kuTG93LCBZTWF4ID0gTWVhblJUICsgQ0kuSGlnaCkKCmRvZGdlID0gcG9zaXRpb25fZG9kZ2UoLjkpCmdncGxvdChkYXRhPXRlbXAsIGFlcyh4PXRyaWFsX2dlbmRlcix5PU1lYW5SVCxmaWxsPXRyaWFsX2dlbmRlcikpICsgCiAgZ2VvbV9iYXIoc3RhdD0naWRlbnRpdHknLHBvc2l0aW9uPWRvZGdlKSArIAogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49WU1pbix5bWF4PVlNYXgpLHdpZHRoPS4yNSxwb3NpdGlvbj1kb2RnZSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICdub25lJykKYGBgCmBgYHtyfQpkb2RnZSA9IHBvc2l0aW9uX2RvZGdlKC45KQoKYWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHRyaWFsX2dlbmRlcikgJT4lCiAgc3VtbWFyaXplKE1lYW5SVCA9IG1lYW4ocmVzaWRfcnQpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dHJpYWxfZ2VuZGVyLHk9TWVhblJULGZpbGw9dHJpYWxfZ2VuZGVyKSkgKyAKICBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScscG9zaXRpb249ZG9kZ2UpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKQpgYGAKCiMjIFJlYWRpbmcgVGltZSBSZXNpZHVhbHMgYnkgQ29uZ3J1ZW5jeSAKCmBgYHtyfQpkb2RnZSA9IHBvc2l0aW9uX2RvZGdlKC45KQoKYWxsX2RhdGEgJT4lIAogIGdyb3VwX2J5KHRyaWFsX2NvbmdydWVuY3kpICU+JQogIHN1bW1hcml6ZShNZWFuUlQgPSBtZWFuKHJlc2lkX3J0KSkgJT4lCiAgZ2dwbG90KGFlcyh4PXRyaWFsX2NvbmdydWVuY3kseT1NZWFuUlQsZmlsbD10cmlhbF9jb25ncnVlbmN5KSkgKyAKICBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScscG9zaXRpb249ZG9kZ2UpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKQpgYGAKCiMjIE15IE1vcnBob2xvZ2ljYWwgVHlwZSBhbmQgR2VuZGVyCgpgYGB7cn0KYWxsX2RhdGEgJT4lCiAgZ3JvdXBfYnkoY29uZGl0aW9uLHRyaWFsX2dlbmRlcixtb3JwaF90eXBlKSAlPiUKICBzdW1tYXJpemUoTWVhblJUID0gbWVhbihyZXNpZF9ydCksIENJLkxvdyA9IGNpLmxvdyhyZXNpZF9ydCksIENJLkhpZ2ggPSBjaS5oaWdoKHJlc2lkX3J0KSkgJT4lCiAgbXV0YXRlKFlNaW4gPSBNZWFuUlQgLSBDSS5Mb3csIFlNYXggPSBNZWFuUlQgKyBDSS5IaWdoKSAlPiUKICBnZ3Bsb3QoYWVzKHg9Y29uZGl0aW9uLHk9TWVhblJULGNvbG9yPXRyaWFsX2dlbmRlcikpICsgCiAgZ2VvbV9wb2ludChzaXplPTMpICsgCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1ZTWluLHltYXg9WU1heCksIHdpZHRoPS4yNSkgKyAKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gaW5hdWd1cmF0aW9uXzIwMjEpICsgCiAgZmFjZXRfd3JhcCh+bW9ycGhfdHlwZSkgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZT00NSwgdmp1c3QgPSAwLjUpKQpgYGAKCiMjIFRhc2sgRmFtaWxpYXJpdHkKCmBgYHtyfQphZ2dfc3BlYWtlcl90cmlhbCA8LSBhbGxfZGF0YSAlPiUKICBncm91cF9ieShjb25kaXRpb24sd29ya2VyaWQpICU+JQogIHN1bW1hcml6ZShNZWFuUlQ9bWVhbihyZXNpZF9ydCkpCmBgYAoKYGBge3J9CmFsbF9kYXRhICU+JQogIGdyb3VwX2J5KHRyaWFsX25vKSAlPiUKICBzdW1tYXJpc2UoTWVhblJUID0gbWVhbihydCkpICU+JQogIGdncGxvdChhZXMoeD10cmlhbF9ubyx5PU1lYW5SVCkpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgZ2VvbV9zbW9vdGgoKSArIAogIHRoZW1lX21pbmltYWwoKQpgYGAKCgojIE1vZGVsIEFuYWx5c2VzCgojIFRlc3RpbmcgTW9kZWxzCgpgYGB7cn0KdGVzdF9tb2RlbCA8LSBsbShyZXNpZF9ydH50cmlhbF9jb25ncnVlbmN5Km1vcnBoX3R5cGUsIGRhdGE9YWxsX2RhdGEpCmBgYAoKYGBge3J9CnN1bW1hcnkodGVzdF9tb2RlbCkKYGBgCmBgYHtyfQp0ZXN0X21vZGVsMiA8LSBsbShyZXNpZF9ydH50cmlhbF9nZW5kZXIsIGRhdGE9YWxsX2RhdGEpCmBgYAoKYGBge3J9CnN1bW1hcnkodGVzdF9tb2RlbDIpCmBgYAoKYGBge3J9CmNvbXBvdW5kc19vbmx5IDwtIGFsbF9kYXRhICU+JQogIGZpbHRlcihtb3JwaF90eXBlID09ICdjb21wb3VuZCcpCmBgYAoKYGBge3J9CmNvbXBvdW5kc19vbmx5IDwtIGNvbXBvdW5kc19vbmx5ICU+JQogIG11dGF0ZShjdHJpYWxfY29uZ3J1ZW5jeSA9IGFzLm51bWVyaWMoYXMuZmFjdG9yKHRyaWFsX2NvbmdydWVuY3kpKS1tZWFuKGFzLm51bWVyaWMoYXMuZmFjdG9yKHRyaWFsX2NvbmdydWVuY3kpKSkpICU+JQogIG11dGF0ZShjdHJpYWxfZ2VuZGVyID0gYXMubnVtZXJpYyhhcy5mYWN0b3IodHJpYWxfZ2VuZGVyKSktbWVhbihhcy5udW1lcmljKGFzLmZhY3Rvcih0cmlhbF9nZW5kZXIpKSkpICU+JQogIG11dGF0ZShjZ2VuZGVyX2xpbmsgPSBzY2FsZShnZW5kZXJfbGluaykpICU+JQogIG11dGF0ZShjZ2VuZGVyX3RvdGFsID0gc2NhbGUoZ2VuZGVyX3RvdGFsKSkKYGBgCgpgYGB7cn0KY29tcG91bmRfbW9kZWwgPC0gbG1lcihyZXNpZF9ydH5jdHJpYWxfY29uZ3J1ZW5jeSpjdHJpYWxfZ2VuZGVyKmNnZW5kZXJfdG90YWwgKyAoMXx3b3JrZXJpZCkgKyAoMXxsZXhlbWUpICsgKDF8bmFtZSksZGF0YSA9IGNvbXBvdW5kc19vbmx5KQpgYGAKCmBgYHtyfQpzdW1tYXJ5KGNvbXBvdW5kX21vZGVsKQpgYGAKCmBgYHtyfQphZG9wdGlvbnNfb25seSA8LSBhbGxfZGF0YSAlPiUKICBmaWx0ZXIobW9ycGhfdHlwZSA9PSAnYWRvcHRpb24nKQpgYGAKCmBgYHtyfQphZG9wdGlvbnNfb25seSA8LSBhZG9wdGlvbnNfb25seSAlPiUKICBtdXRhdGUoY3RyaWFsX2NvbmdydWVuY3kgPSBhcy5udW1lcmljKGFzLmZhY3Rvcih0cmlhbF9jb25ncnVlbmN5KSktbWVhbihhcy5udW1lcmljKGFzLmZhY3Rvcih0cmlhbF9jb25ncnVlbmN5KSkpKSAlPiUKICBtdXRhdGUoY3RyaWFsX2dlbmRlciA9IGFzLm51bWVyaWMoYXMuZmFjdG9yKHRyaWFsX2dlbmRlcikpLW1lYW4oYXMubnVtZXJpYyhhcy5mYWN0b3IodHJpYWxfZ2VuZGVyKSkpKSAlPiUKICBtdXRhdGUoY2dlbmRlcl9saW5rID0gc2NhbGUoZ2VuZGVyX2xpbmspKSAlPiUKICBtdXRhdGUoY2dlbmRlcl90b3RhbCA9IHNjYWxlKGdlbmRlcl90b3RhbCkpCmBgYAoKYGBge3J9CmFkb3B0aW9uc19tb2RlbCA8LSBsbWVyKHJlc2lkX3J0fmN0cmlhbF9jb25ncnVlbmN5KmN0cmlhbF9nZW5kZXIqY2dlbmRlcl90b3RhbCArICgxfHdvcmtlcmlkKSArICgxfGxleGVtZSkgKyAoMXxuYW1lKSxkYXRhID0gYWRvcHRpb25zX29ubHkpCmBgYAoKYGBge3J9CnN1bW1hcnkoYWRvcHRpb25zX21vZGVsKQpgYGAKCiMjIEZ1bGwgTW9kZWwKCmBgYHtyfQphbGxfZGF0YSA8LSBhbGxfZGF0YSAlPiUKICBtdXRhdGUoY3RyaWFsX2NvbmdydWVuY3kgPSBhcy5udW1lcmljKGFzLmZhY3Rvcih0cmlhbF9jb25ncnVlbmN5KSktbWVhbihhcy5udW1lcmljKGFzLmZhY3Rvcih0cmlhbF9jb25ncnVlbmN5KSkpKSAlPiUKICBtdXRhdGUoY3RyaWFsX2dlbmRlciA9IGFzLm51bWVyaWMoYXMuZmFjdG9yKHRyaWFsX2dlbmRlcikpLW1lYW4oYXMubnVtZXJpYyhhcy5mYWN0b3IodHJpYWxfZ2VuZGVyKSkpKSAlPiUKICBtdXRhdGUoY2dlbmRlcl9saW5rID0gc2NhbGUoZ2VuZGVyX2xpbmspKSAlPiUKICBtdXRhdGUoY2dlbmRlcl90b3RhbCA9IHNjYWxlKGdlbmRlcl90b3RhbCkpICU+JQogIG11dGF0ZShjbW9ycGhfdHlwZSA9IGFzLm51bWVyaWMoYXMuZmFjdG9yKG1vcnBoX3R5cGUpKS1tZWFuKGFzLm51bWVyaWMoYXMuZmFjdG9yKG1vcnBoX3R5cGUpKSkpCmBgYAoKYGBge3J9CmNvbXBsZXhfbW9kZWwgPC0gbG1lcihyZXNpZF9ydH5jdHJpYWxfY29uZ3J1ZW5jeSpjdHJpYWxfZ2VuZGVyKmNnZW5kZXJfdG90YWwgKyAoMXx3b3JrZXJpZCkgKyAoMXxsZXhlbWUpLGRhdGEgPSBhbGxfZGF0YSkKYGBgCgpgYGB7cn0Kc3VtbWFyeShjb21wbGV4X21vZGVsKQpgYGAKCiMjIEdlbmRlciBUb3RhbAoKYGBge3J9CmlkZW9sb2d5X21vZGVsIDwtIGxtZXIocmVzaWRfcnR+Y3RyaWFsX2NvbmdydWVuY3kqY3RyaWFsX2dlbmRlcipjZ2VuZGVyX2xpbmsgKyAoMXx3b3JrZXJpZCkgKyAoMXxsZXhlbWUpICsgKDF8bmFtZSksIGRhdGE9YWxsX2RhdGEpCmBgYAoKYGBge3J9CnN1bW1hcnkoaWRlb2xvZ3lfbW9kZWwpCmBgYAoKCiMgQ29tbWVudHMKCmBgYHtyfQphbGxfZGF0YSAlPiUKICBncm91cF9ieSh3b3JrZXJpZCxwb2xpX3BhcnR5KSAlPiUKICBzdW1tYXJpc2UoY29tbWVudHMgPSBwYXN0ZSh1bmlxdWUoc3ViamVjdF9pbmZvcm1hdGlvbi5jb21tZW50cykpKSAlPiUKICBzZWxlY3QocG9saV9wYXJ0eSxjb21tZW50cykKYGBgCgojIFRlc3RpbmcgR3JvdW5kcwoKIyMgQ2hlY2tpbmcgdGhlIHRpbWVzCgpgYGB7cn0KbmV3X3RveSA8LSByZWFkLmNzdignbWF6ZV90YXNrXzEtbWVyZ2VkLmNzdicpICU+JQogIGZpbHRlcih0cmlhbF9pZCE9ICdleGFtcGxlJykgJT4lCiAgZmlsdGVyKHJlc3BvbnNlX2NvcnJlY3QgIT0gMCkgJT4lCiAgbXV0YXRlKHRyaWFsX2dlbmRlciA9IGlmZWxzZShjb25kaXRpb249PSduZXV0cmFsX2ZlbWFsZScgfCBjb25kaXRpb24gPT0gJ2NvbmdydWVudF9mZW1hbGUnLCdmZW1hbGUnLCdtYWxlJykpICU+JQogIG11dGF0ZSh0cmlhbF9jb25ncnVlbmN5ID0gaWZlbHNlKGNvbmRpdGlvbj09J2NvbmdydWVudF9tYWxlJyB8IGNvbmRpdGlvbiA9PSAnY29uZ3J1ZW50X2ZlbWFsZScsJ2NvbmdydWVudCcsJ25ldXRyYWwnKSkKYGBgCgpgYGB7cn0KbmV3X3RveSAlPiUKICBncm91cF9ieSh3b3JkX2lkeCx0cmlhbF9nZW5kZXIpICU+JQogIHN1bW1hcml6ZShNZWFuUlQgPSBtZWFuKHJ0KSkgJT4lCiAgZ2dwbG90KGFlcyh4PXdvcmRfaWR4LCB5PWxvZyhNZWFuUlQpLCBjb2xvcj10cmlhbF9nZW5kZXIpKSArIAogIGdlb21fbGluZSgpICsgCiAgZ2VvbV9wb2ludCgpCmBgYAoKYGBge3J9Cm5ld190b3kgJT4lCiAgZ3JvdXBfYnkod29yZF9pZHgsdHJpYWxfZ2VuZGVyKSAlPiUKICBzdW1tYXJpemUoTWVhblJUID0gbWVhbihydCkpICU+JQogIGdncGxvdChhZXMoeD13b3JkX2lkeCwgeT1NZWFuUlQsIGNvbG9yPXRyaWFsX2dlbmRlcikpICsgCiAgZ2VvbV9saW5lKCkgKyAKICBnZW9tX3BvaW50KCkKYGBgCgpgYGB7cn0KYWxsX2RhdGEgJT4lCiAgZmlsdGVyKCFpcy5uYShwb2xpX3BhcnR5KSkgJT4lCiAgZ3JvdXBfYnkocG9saV9wYXJ0eSkgJT4lCiAgc3VtbWFyaXplKE1lYW5HZW5kZXJUb3RhbCA9IG1lYW4oZ2VuZGVyX3RvdGFsKSkgJT4lCiAgZ2dwbG90KGFlcyh4PXBvbGlfcGFydHksIHk9TWVhbkdlbmRlclRvdGFsKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZV9taW5pbWFsKCkgKyAKICBsYWJzKHk9Ik1lYW4gR2VuZGVyIFRvdGFsIiwgeD0iUG9saXRpY2FsIFBhcnR5IikKYGBgCgpgYGB7cn0KYWxsX2RhdGEgJT4lCiAgZmlsdGVyKCFpcy5uYShzdWJqZWN0X2luZm9ybWF0aW9uLmdlbmRlcikpICU+JQogIGdyb3VwX2J5KHN1YmplY3RfaW5mb3JtYXRpb24uZ2VuZGVyKSAlPiUKICBzdW1tYXJpemUoTWVhbkdlbmRlclRvdGFsID0gbWVhbihnZW5kZXJfdG90YWwpKSAlPiUKICBnZ3Bsb3QoYWVzKHg9c3ViamVjdF9pbmZvcm1hdGlvbi5nZW5kZXIsIHk9TWVhbkdlbmRlclRvdGFsKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZV9taW5pbWFsKCkgKyAKICBsYWJzKHk9Ik1lYW4gR2VuZGVyIFRvdGFsIiwgeD0iUGFydGljaXBhbnQgR2VuZGVyIikKYGBgCgpSc2NyaXB0IG1lcmdlX3Jlc3VsdHMuUiBtYXplX3Rhc2tfMS1tZXJnZWQuY3N2IGRlbXMgbWF6ZV90YXNrXzItbWVyZ2VkLmNzdiByZXBz